package com.ruoyi.translate.controller;

import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ResourceLoader;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.common.util.ListConvertMap;
import com.constant.TransactionConst;
import com.email.EmailUtil;
import com.ruoyi.center.domain.NoticeCenter;
import com.ruoyi.center.service.INoticeCenterService;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.translate.domain.Translate;
import com.ruoyi.translate.service.ITranslateService;
import com.ruoyi.user.service.IMgUserService;
import com.ruoyi.web.core.config.Template;
import com.ruoyi.common.utils.file.FileReaderContent;
import com.ruoyi.common.utils.http.FileDownloader;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.manager.domain.MgServiceManager;
import com.ruoyi.manager.service.IMgServiceManagerService;
import com.ruoyi.order.domain.MgOrder;
import com.ruoyi.order.service.IMgOrderService;
import com.ruoyi.oss.config.OssConfig;
import com.ruoyi.pay.manager.domain.PayManager;
import com.ruoyi.pay.manager.service.IPayManagerService;
import com.ruoyi.recharge.domain.Recharge;
import com.ruoyi.recharge.service.IRechargeService;
import com.ruoyi.common.core.page.TableDataInfo;

/**
 * 发票Controller
 * 
 * @author ruoyi
 * @date 2024-01-18
 */
@RestController
@RequestMapping("/translate/translate")
public class TranslateController extends BaseController {
	@Autowired
	private ITranslateService translateService;

	ResourceLoader resourceLoader;

	IMgServiceManagerService serviceManager;

	INoticeCenterService centerService;

	IRechargeService chargeService;

	ThreadPoolTaskExecutor threadPoolTaskExecutor;

	IPayManagerService managerService;

	IMgUserService mgUserService;

	IMgOrderService orderService;;

	EmailUtil emailUtil;

	OssConfig config;

	Template template;

	@Resource
	public void setOrderService(IMgOrderService orderService) {
		this.orderService = orderService;
	}

	@Resource
	public void setManagerService(IPayManagerService managerService) {
		this.managerService = managerService;
	}

	@Resource
	public void setResourceLoader(ResourceLoader resourceLoader) {
		this.resourceLoader = resourceLoader;
	}

	@Resource
	public void setTemplate(Template template) {
		this.template = template;
	}

	@Resource
	public void setEmailUtil(EmailUtil emailUtil) {
		this.emailUtil = emailUtil;
	}

	@Resource
	public void setMgUserService(IMgUserService mgUserService) {
		this.mgUserService = mgUserService;
	}

	@Resource(name = "threadPoolTaskExecutor")
	public void setThreadPoolTaskExecutor(ThreadPoolTaskExecutor threadPoolTaskExecutor) {
		this.threadPoolTaskExecutor = threadPoolTaskExecutor;
	}

	@Autowired
	public void setChargeService(IRechargeService chargeService) {
		this.chargeService = chargeService;
	}

	@Autowired
	public void setServiceManager(IMgServiceManagerService serviceManager) {
		this.serviceManager = serviceManager;
	}

	@Autowired
	public void setCenterService(INoticeCenterService centerService) {
		this.centerService = centerService;
	}

	@Autowired
	public void setConfig(OssConfig config) {
		this.config = config;
	}

	/**
	 * 查询发票列表
	 */
	@PreAuthorize("@ss.hasPermi('translate:translate:list')")
	@GetMapping("/list")
	public TableDataInfo list(Translate translate) {
		startPage();
		List<Translate> list = translateService.selectList(translate);

		if (0 == list.size()) {
			return getDataTable(list);
		}

		String pic = "https://".concat(config.getURL());

		Translate t;

		String file;

		for (int i = 0; i < list.size(); i++) {
			t = list.get(i);

			file = t.getFile();
			if (null != file && 0 != file.length()) {
				t.setFile(pic.concat(file));
			}
		}

		return getDataTable(list);
	}

	/**
	 * 导出发票列表
	 */
	@PreAuthorize("@ss.hasPermi('translate:translate:export')")
	@Log(title = "发票", businessType = BusinessType.EXPORT)
	@PostMapping("/export")
	public void export(HttpServletResponse response, Translate translate) {
		List<Translate> list = translateService.selectList(translate);
		ExcelUtil<Translate> util = new ExcelUtil<Translate>(Translate.class);

		util.hideColumn("createTime");

		util.exportExcel(response, list, "发票数据");
	}

	/**
	 * 获取发票详细信息
	 */
	@PreAuthorize("@ss.hasPermi('translate:translate:query')")
	@GetMapping(value = "/{id}")
	public AjaxResult getInfo(@PathVariable("id") Integer id) {
		return success(translateService.selectById(id));
	}

	/**
	 * 新增发票
	 */
	@PreAuthorize("@ss.hasPermi('translate:translate:add')")
	@Log(title = "发票", businessType = BusinessType.INSERT)
	@PostMapping
	public AjaxResult add(@RequestBody Translate translate) {
		return toAjax(translateService.insert(translate));
	}

	/**
	 * 修改发票
	 */
	@PreAuthorize("@ss.hasPermi('translate:translate:edit')")
	@Log(title = "发票", businessType = BusinessType.UPDATE)
	@PutMapping
	@Transactional
	public AjaxResult edit(@RequestBody Translate translate) {
		int id = translate.getId().intValue();

		Long auditStatus = translate.getAuditStatus();

		if (null == auditStatus) {
			return AjaxResult.error("审核状态不能为空");
		}

		if (auditStatus != 1) {

			return toAjax(translateService.update(translate));
		}

		Translate dataSource = this.translateService.selectById(id);

		// 不通过

		BigDecimal amount = null;

		Integer assocId = null;
		String notice = "", title = "";


		if (0 == dataSource.getType()) {

			Recharge selectById = chargeService.selectById(dataSource.getAssocId());

			amount = selectById.getAccount();

			if (null == amount) {
				return AjaxResult.error("金额不能为空");
			}

			assocId = selectById.getId();

			Recharge charge = new Recharge();

			charge.setId(selectById.getId());


			charge.setTranslate((byte) 3);

			chargeService.update(charge);
			
			title = "开票通知(预存)";
			
			notice = "您的预存金额【¥" + amount + "】开票申请未通过:审核原因:" + translate.getReason() + "。";
			

		} else if (1 == dataSource.getType()) {

			PayManager selectById = managerService.selectById(dataSource.getAssocId());

			amount = selectById.getPriceSum();

			if (null == amount) {
				return AjaxResult.error("金额不能为空");
			}

			assocId = selectById.getId();

			PayManager manager = new PayManager();
			
			manager.setTranslate((byte) 3);
			
			title = "开票通知(订单)";

			manager.setId(selectById.getId());

			managerService.update(manager);

			notice = "您的【" + selectById.getServiceNames() + "】订单" +selectById.getOrderSnId() + "开票申请未通过:审核原因:" + translate.getReason() + "。";
		}

		if (null == amount || null == assocId) {
			return AjaxResult.error("金额不能为空或关联id不能为空");
		}

		// 您的预存金额【¥1000】开票申请:审核原因:未通过原因描述。

		NoticeCenter center = new NoticeCenter();

		center.setUserId(dataSource.getUserId());

		center.setJump((byte) 0);

		center.setTitle(title);
		
		center.setNoticeContent(notice);

		center.setPlatform(0);

		center.setNoticeType(2);

		center.setTypeId(assocId);

		center.setReadStatus(0);

		centerService.insert(center);

		return toAjax(translateService.update(translate));
	}

	private static String[] noticeContent = new String[] {
			// 0 预存发票
			"您的预存金额【#{TYPE_NAME}】单号#{ORDER_SN}申请的电子发票已成功开具", "您的【#{TYPE_NAME}】订单#{ORDER_SN}申请的电子发票已成功开具" };

	/**
	 * 修改发票
	 */
	@PreAuthorize("@ss.hasPermi('translate:translate:upload')")
	@Log(title = "发票", businessType = BusinessType.UPDATE)
	@PutMapping("translate")
	@Transactional
	public AjaxResult translate(@RequestBody Translate translate) {
		Long id = translate.getId();

		if (null == id) {
			return AjaxResult.error("id不能为空");
		}

		Translate dataSource = translateService.selectById(id.intValue());

		String file = translate.getFile();

		if (null == file) {
			return AjaxResult.error("发票不能为空");
		}

		String url = config.getURL();

		String original = file.replaceAll("http://", "").replaceAll("https://", "").replaceAll(url, "");

		translate.setFile(original);

		NoticeCenter insertNoticeUser = this.insertNoticeUser(dataSource, "", "开票通知", (byte) 1);

		if (null == insertNoticeUser) {
			throw new IllegalStateException("找不到服务类型");
		}

		centerService.insert(insertNoticeUser);

		int update = translateService.update(translate);

		updateAssoc(dataSource);

		threadPoolTaskExecutor.execute(() -> {

			String tempPath = System.getenv("TEMP") + "/开票通知." + file.substring(file.lastIndexOf(".") + 1);

			FileDownloader.downloadFile(file, tempPath);

			String classPath = template.getHtml();

			org.springframework.core.io.Resource resource = resourceLoader.getResource(classPath);

			try {
				String string = FileReaderContent.read(resource.getInputStream());

				String content = noticeContent[dataSource.getType()];

				content = content.replace("#{TYPE_NAME}", insertNoticeUser.getTypeName()).replace("#{ORDER_SN}",
						dataSource.getOrderSn());

				// 您的【""】订单KT240305123456申请的电子发票已成功开具!请注意查收
				string = string.replace("#{CONENT}", content).trim();

//				emailUtil.sendMessage(dataSource.getEmail(), "开票", string);

				emailUtil.sendMessageCarryFile(dataSource.getEmail(), "来自科藤学术中心的电子发票开具通知邮件", string, new File(tempPath));
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		});

		return toAjax(update);
	}

	protected void updateAssoc(Translate dataSource) {
		Byte type = dataSource.getType();

		Integer assocId = dataSource.getAssocId();

		if (1 == dataSource.getAuditStatus()) {
			return;
		}

		if (0 == type) {

			Recharge selectById = chargeService.selectById(assocId);

			Recharge charge = new Recharge();

			charge.setId(selectById.getId());

			charge.setTranslate((byte) 2);

			chargeService.update(charge);

		} else if (1 == type) {

			PayManager selectById = managerService.selectById(assocId);

			PayManager manager = new PayManager();

			manager.setId(selectById.getId());

			manager.setTranslate((byte) 2);

			managerService.update(manager);
		}
	}

	private NoticeCenter insertNoticeUser(Translate dataSource, String message, String title, byte jump) {

		Byte type = dataSource.getType();

		Integer assocId = Integer.valueOf(dataSource.getAssocId());

		String content = "";

		NoticeCenter center;
		
		String typeName = TransactionConst.Type[dataSource.getInvoiceContent().intValue()];

		if (1 == type) {
//			List<MgServiceManager> selectMgServiceManagerList = serviceManager
//					.selectMgServiceManagerList(new MgServiceManager());
//
//			Map<Integer, MgServiceManager> listToMap = ListConvertMap.listToMap(selectMgServiceManagerList,
//					MgServiceManager::getId);

//			List<MgOrder> selectOrderByPayManagerId = orderService.selectOrderByPayManagerId(new int[] { assocId });

//			MgServiceManager mgServiceManager;

//			for (MgOrder item : selectOrderByPayManagerId) {
//				mgServiceManager = listToMap.get(item.getServiceId());
//
//				if (null == mgServiceManager) {
//					return null;
//				}
			    PayManager payManager = managerService.selectById(assocId);

				content = "您的【" + payManager.getServiceNames() + "】订单" + dataSource.getOrderSn() + "已开票，电子发票已发送到已绑的邮箱中，请注意查收。";

				center = new NoticeCenter();
				center.setTypeName(typeName);
				parseNoticeUserCenter(dataSource, title, jump, assocId, content, center);

				center.setTranslateType((byte) 2);

				return center;
//			}

		} else {
			Recharge recharge = chargeService.selectById(assocId);

			center = new NoticeCenter();

			center.setTranslateType((byte) 1);

			BigDecimal account = recharge.getAccount();

			center.setTypeName(account.toString());

			content = "您的预存金额【" + account + "】" + dataSource.getOrderSn() + "已开票，电子发票已发送到已绑的邮箱中，请注意查收。";

			parseNoticeUserCenter(dataSource, title, jump, assocId, content, center);

			return center;

		}
	}

	private void parseNoticeUserCenter(Translate dataSource, String title, byte jump, Integer assocId, String content,
			NoticeCenter center) {
		center.setUserId(Integer.valueOf(dataSource.getUserId()));

		center.setNoticeType(2);

		center.setTitle(title);

		center.setTypeId(assocId);

		center.setNoticeContent(content);

		center.setJump((byte) 1);

		center.setJump(jump);

		center.setAdminId(0);

		long timeMillis = System.currentTimeMillis() / 1000;

		center.setCreateTime(timeMillis);

		center.setUpdateTime(timeMillis);
	}

	/**
	 * 删除发票
	 */
	@PreAuthorize("@ss.hasPermi('translate:translate:remove')")
	@Log(title = "发票", businessType = BusinessType.DELETE)
	@DeleteMapping("/{ids}")
	public AjaxResult remove(@PathVariable Integer[] ids) {
		return toAjax(translateService.deleteByIds(ids));
	}
}
